XDL ImageView 활용 네 번째

NXImageView를 활용하여 여러 장의 GeoTIFF 파일을 도시하는 기능을 구현합니다.

들어가기 전에

본 튜터리얼을 공부하기 전에 먼저 "XDL ImageView 활용 첫 번째”를 먼저 선행하시기 바랍니다.

1 예제 프로그램 만들기
1.1 "XDL_ImageView4" 이름으로 “Windows Forms 앱(.NET Framework)” 프로젝트를 생성한다.

자세한 설명은 "영상도시 툴 만들기 1"의 1. 예제 프로그램 만들기를 참고하기 바란다.


1.2 [도구상자]의 [항목선택]에 NXImage의 컨트롤을 추가한다.

영상도시 툴 만들기 1의 1.4 [도구상자]의 [항목선택] 부분을 참고하기 바란다.


1.3 “NXDL.dll”, “NXDLcc.dll”, “NXDLgr.dll”, “NXDLio.dll”, “NXDLrs.dll, “NXImage.dll” 파일을 참조 추가한다.

자세한 설명은 "영상도시 툴 만들기 1"의 1.5 참조추가 이후를 참고하기 바란다.

2 메뉴 생성하기
2.1 [도구상자]의 MenuStrip을 선택하고 Form1의 상단부에 드래그하여 배치한다.
2.2 메뉴에 [File]-[Open]을 입력하여 생성한다.
3 NXImageView 컨트롤 올리기
3.1 Form1에 NXImageView 컨트롤를 추가하고 [부모컨테이너에서 도킹]을 한다.
3.2 NXImageLayerComposites를 끌어다 NXImageView 컨트롤 위에 올려 놓는다.
3.3 [F5]키를 눌러 프로그램을 실행한다. 아래와 같이 NXImageView 컨트롤이 있는 프로그램이 실행된다.
4 영상 열기
4.1 디자인창에서 Toolbar의 [File]-[Open]을 더블 클릭하여 함수를 자동 생성한다.

C#

                                
private void OpenToolStripMenuItem_Click(object sender, EventArgs e)
{
}
                                
                            

4.2 View 구현시 필요한 XRasterIO객체를 선언한다.

C#

                                    
public XRasterIO m_RasterIO;    //영상의 입출력을 담당할 객체 선언
                                    
                                

4.3 Form1 생성자에서 XRasterIO의 객체 생성 및 NXImageLayerComposites에 대한 속성을 변경한다.

C#

                                    
public Form1()
{
    InitializeComponent();

    String StrError;
    m_RasterIO = new XRasterIO();   // 객체 생성
    if (m_RasterIO.Initialize(out StrError) == false) // 영상 입출력 객체 초기화
    {
        MessageBox.Show(StrError);
    }

    nxImageLayerComposites1.LayerVisible = true; // 영상레이어를 보이도록 속성을 변경
}
                                    
                                

4.4 File 열기 버튼을 눌렀을 때 생성될 Open 대화상자와 선택된 파일에 대한 XRSLoadFile 객체를 생성한다.

C#

                                    
private void OpenToolStripMenuItem_Click(object sender, EventArgs e)
{
    // 파일 Open을 수행한다.
    OpenFileDialog openFileDialog = new OpenFileDialog();
    openFileDialog.Filter = "GeoTiff file(*.tif)|*.TIF||";
    openFileDialog.RestoreDirectory = true;

    if (openFileDialog.ShowDialog() != DialogResult.OK) return;

    string strFilePath = openFileDialog.FileName;

    // FileDriverManger를 통해 XRSLoadFile을 생성한다. 
    // GeoTIFF 직접 로딩하는 경우 영상크기가 큰 경우 도시 속도를 위해서 LOD가 필요하기 때문에 필요한 경우 같은 폴더에 .xld파일을 생성한다.
    string strError;
    XRSLoadFile xrsFileInput1 = m_RasterIO.LoadFile(strFilePath, out strError, false, eIOCreateXLDMode.All_NoMsg);
    if (xrsFileInput1 == null) return;

    // 다시 Original Image에 대한 Composite와 Processed Image에 대한 Composite를 생성하여 뷰 컨트롤에 도시한다.
    XDMComposite newComp = CreateComposite(xrsFileInput1, 0, 1, 2);

    // 기존에 생성되어 있는 Composite가 있다면 Lock을 걸어 도시 수행을 잠시 멈춘다. 
    nxImageLayerComposites1.Lock();

    // nxImageLayerComposites1개체에 있는 XDMCompManager들을 꺼낸다.
    // XDMCompManager가 실제로 Composite들의 관리를 수행한다. 
    XDMCompManager xdmCompManager = nxImageLayerComposites1.GetXDMCompManager();

    // 생성된 Composite를 XDMCompManager에 추가한다.
    xdmCompManager.AddXDMComposite(ref newComp);

    // 전체 화면 보기를 설정한다.
    nxImageLayerComposites1.ZoomFit();

    // 화면 업데이트를 수행한다. 
    nxImageLayerComposites1.Invalidate();

    // Lock을 다시 풀어 준다. 
    nxImageLayerComposites1.UnLock();
}
                                    
                                

C#

                                    
XDMComposite CreateComposite(XRSLoadFile xrsFileInput, int nBandIdx0, int nBandIdx1, int nBandIdx2)
{
    // XDMComposite를 생성한다.
    XDMComposite newComp = new XDMComposite();

    // 로딩된 파일로부터 밴드의 개수가 칼라로 그릴 것인지 흑백으로 그릴 것인지를 판단한다.
    // 만약 3개 미만인 경우는 Gray모드로 그리고, 3개 이상인 경우는 칼라로 그린다.
    int nNumBand = xrsFileInput.NumBand;
    if (nNumBand < 3)   // 3개 미만의 밴드를 가지고 있는 경우
    {
        // Default로 0번째 밴드를 Gray모드로 그린다. 
        XDMBand band = xrsFileInput.GetBandAt(0);

        // Gray Mode로 그리는 것을 설정
        newComp.Mode = eCompMode.Gray;

        // Composite의 0번에 Band설정, Gray모드에서는 0번 밴드만을 인식한다. 
        newComp.SetBand(ref band, nBandIdx0);
        // 영상 Enhancement를 위해 Histogram의 범위 설정(정규분포 95% 영역)
        newComp.SetCutType(eCompCutType.Ct95, 0);
        // 영상 Enhancement를 위해 Histogram적용시 전체 영역에 대한 
        // Histogram(Band)설정, Visible은 현재 영역
        newComp.SetStretchCoverage(eCompStretchCoverage.Band, 0);
        // 영상 Enhancement를 위해 Histogram의 Stretch형태 설정(Gaussian으로 설정)
        newComp.SetStretchType(eCompStretchType.Gaussian, 0);

    }
    else // 3개 이상의 밴드를 가지고 있는 경우 
    {
        XDMBand band1 = xrsFileInput.GetBandAt(nBandIdx0);
        XDMBand band2 = xrsFileInput.GetBandAt(nBandIdx1);
        XDMBand band3 = xrsFileInput.GetBandAt(nBandIdx2);
        newComp.Name = xrsFileInput.FileName; // 파일 이름을 Composite이름으로 설정

        newComp.Mode = eCompMode.RGB;  // RGB Mode로 그리는 것을 설정
        newComp.SetBand(ref band3, nBandIdx0); // Composite의 0번에 Band설정, Blue Channel설정 
        newComp.SetBand(ref band2, nBandIdx1); // Composite의 1번에 Band설정, Green Channel설정
        newComp.SetBand(ref band1, nBandIdx2); // Composite의 2번에 Band설정, Red Channel설정

        for (int i = 0; i < 3; i++)
        {
            // 영상 Enhancement를 위해 Histogram의 범위 설정(정규분포 95% 영역)
            newComp.SetCutType(eCompCutType.Ct95, i);
            // 영상 Enhancement를 위해 Histogram적용시 전체 영역에 대한 
            // Histogram(Band)설정, Visible은 현재 영역
            newComp.SetStretchCoverage(eCompStretchCoverage.Band, i);
            // 영상 Enhancement를 위해 Histogram의 Stretch형태 설정(Gaussian으로 설정)
            newComp.SetStretchType(eCompStretchType.Gaussian, i);
        }
    }

    // 생성된 Composite를 XDMCompManager객체에 추가한다.        
    return newComp;
}
                                    
                        	    

4.5 [F5]키를 눌러 프로그램을 실행한다. [File]-[Open] 메뉴를 눌러 1.tif 파일을 연다. 다시 [File]-[Open] 메뉴를 눌러 2.tif 파일을 연다.

두 영상이 위치에 맞게 중첩된 결과를 확인할 수 있다.

1 예제 프로그램 만들기
1.1 "XDL_ImageView4" 이름으로 “WPF 앱(.NET Framework)” 프로젝트를 생성한다.

자세한 설명은 "영상도시 툴 만들기 1"의 1. 예제 프로그램 만들기를 참고하기 바란다.


1.2 프로젝트에 “NXDL.dll”, “NXDLio.dll”, “NXDLrs.dll”, “NXImage.dll” 파일을 참조추가한다.

자세한 설명은 "영상도시 툴 만들기 1"의 1.5 참조추가 이후를 참고하기 바란다.


1.3 ImageView 컨트롤을 활용하기 위해 MainWindow.xaml 창에서 namespace를 다음과 같이 추가한다.

자세한 설명은 "영상도시 툴 만들기 1"의 1.7 항목을 참고하기 바란다.

2 메뉴 생성하기
2.1 MainWindow.xaml창에서 기본으로 생성된 Grid 레이아웃에 Grid.RowDefinition을 이용하여 두 개의 Row을 생성한다. [도구 상자]에서 Menu를 드래그하여 Row 의 첫 번째 Cell에 배치하고, MenuItem 항목을 추가한다. 표를 참고하여 [File]-[Open]을 입력하여 생성한다. (메뉴 생성에 대한 자세한 설명은 XDL ImageView1을 참고한다.)
Control type Header Name
MenuItem _File
MenuItem _Open openFileMenuItem

최종적으로 다음과 같은 XAML 코드를 생성한다.

XAML

                                    
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="30"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>

    <Menu Grid.Row="0">
        <MenuItem Header="_File" Margin="5,5,0,0">
            <MenuItem x:Name="openFileMenuItem" Header="_Open"/>
        </MenuItem>
    </Menu>
</Grid>
                                    
                                
3 NXImageView 컨트롤 올리기
3.1 XAML의 Grid 레이아웃 내부에서 두 번째 Cell에 Grid를 배치하고 [도구 상자]에서 WindowsFormsHost 컨트롤을 드래그하여 생성하거나, XAML 창의 Grid 레이아웃에 WindowsFormsHost를 입력하여 생성한다(XDL_ImageView1을 참고). 이는 Window forms를 Hosting 해주는 개체이며 Window Forms Control을 사용할 때 이용된다. (WindowsFormsIntegration과 System.Window.Forms을 어셈블리에 대한 참조 추가를 한다.)

3.2 Grid 레이아웃에 WindowFormsHost를 입력하고 앞서 추가한 namespace인 nxImage를 이용하여 NXImageView컨트롤을 불러온다. 이 NXImageView의 이름은 nxImageView1으로 한다.

C#

                                    
<Grid Grid.Row="1">
       <WindowsFormsHost  Margin="3,0,3,3">
           <nxImage:NXImageView x:Name="nxImageView1">

           </nxImage:NXImageView>
       </WindowsFormsHost>
</Grid>
                                    
                                

3.3 NXImageView컨트롤에 NXImageLayerComposite 컨트롤을 입력한다. 이 NXImageLayerComposite의 이름(Name)은 nxImageLayerComposites1이라고 한다.

NXImageLayerComposites은 영상의 밴드들을 합성시켜서 화면에 도시하는 기능을 수행하는 컨트롤이다.

XAML

                                    
<Grid Grid.Row="1">
       <WindowsFormsHost  Margin="3,0,3,3">
           <nxImage:NXImageView x:Name="nxImageView1">
               <nxImage:NXImageView.Controls>
                   <nxImage:NXImageLayerComposites x:Name="nxImageLayerComposites1"/>
               </nxImage:NXImageView.Controls>
           </nxImage:NXImageView>
       </WindowsFormsHost>
</Grid>
                                    
                                

3.4 [F5]키를 눌러 프로그램을 실행한다.
4 NXImageView에 영상 파일 도시하기
4.1 XAML창에서 [File]-[Open] 에 대한 함수를 생성한다. openFileMenuItem XAML코드에 대해, [속성] 창에서 Click 이벤트 칸을 더블 클릭하여 Click 자동함수를 생성한다.

C#

                                    
    private void openFileMenuItem_Click(object sender, RoutedEventArgs e)
    {

    }
                                    
                                

4.2 View 구현시 필요한 XRasterIO 객체를 선언한다.

C#

                                    
    public XRasterIO m_RasterIO;    //영상의 입출력을 담당할 객체 선언
                                    
                                

4.3 Window생성자에서 XRasterIO의 객체 생성 및 NXImageLayerComposites에 대한 속성을 변경한다.

C#

                                    
    public MainWindow()
    {
        InitializeComponent();
        String StrError;
        m_RasterIO = new XRasterIO();                       // 객체 생성
        if (m_RasterIO.Initialize(out StrError) == false)   // 영상 입출력 객체 초기화
        {
            MessageBox.Show(StrError);
        }
        NxImageLayerComposite1.LayerVisible = true; // 영상레이어를 보이도록 속성을 변경
    }
                                    
                                

4.4 [File]-[Open] 버튼을 눌렀을 때 생성될 Open 대화상자와 선택된 파일에 대한 XRSLoadFile객체를 생성한다.

C#

                                    
    private void openFileMenuItem_Click(object sender, RoutedEventArgs e)
    {
        // 파일 Open을 수행한다.
        OpenFileDialog openFileDialog = new OpenFileDialog();
        openFileDialog.Filter = "GeoTiff file(*.tif)|*.TIF||";
        openFileDialog.RestoreDirectory = true;

        Nullable<bool> result = openFileDialog.ShowDialog();
        if (result != true) return;

        string strFilePath = openFileDialog.FileName;

        // FileDriverManger를 통해 XRSLoadFile를 생성한다.
        // GeoTIFF를 직접 로딩하는 경우 영상 크기가 큰 경우 도시 속도를 위해서 LOD가 필요하기 때문에 필요한 경우 같은 폴더에 .xdl 파일을 생성한다.
        string strError;
        XRSLoadFile xrsFileInput1 = m_RasterIO.LoadFile(strFilePath, out strError,
            false, eIOCreateXLDMode.All_NoMsg);
        if (xrsFileInput1 == null) return;

        // 다시 Original Imange에 대한 Composite와 Processed Image에 대한 Composite를 생성하여 뷰 컨트롤에 도시한다.
        XDMComposite newComp = CreateComposite(xrsFileInput1, 0, 1, 2);

        // 기존에 생성되어 있는 Composite가 있다면 Lock을 걸어 도시 수행을 잠시 멈춘다.
        nxImageLayerComposites1.Lock();

        // nxImageLayerCompostie1개체에 있는 XDMCompManager들을 꺼낸다.
        // XDMCompManager가 실제로 Composite들의 관리를 수행한다.
        XDMCompManager xdmCompManager = nxImageLayerComposites1.GetXDMCompManager();

        // 생성된 Compostie를 XDMCompManager에 추가한다.
        xdmCompManager.AddXDMComposite(ref newComp);

        // 전체 화면 보기를 설정한다.
        nxImageLayerComposites1.ZoomFit();

        // 화면 업데이트를 수행한다.
        nxImageLayerComposites1.Invalidate();

        // Lock을 다시 풀어 준다.
        nxImageLayerComposites1.UnLock();
    }
                                    
                                

C#

                                    
    XDMComposite CreateComposite(XRSLoadFile xrsFileInput, int nBandIdx0, int nBandIdx1, int nBandIdx2)
    {
        // XDMComposite를 생성한다.
        XDMComposite newComp = new XDMComposite();

        // 로딩된 파일로부터 밴드의 개수가 칼라로 그릴 것인지 흑백으로 그릴 것인지 판단한다.
        // 만약 3개 미만인 경우에는 Gray모드로 그리고, 3개 이상인 경우는 칼라로 그린다.
        int nNumBand = xrsFileInput.NumBand;
        if (nNumBand < 3)   // 3개 미만의 밴드를 가지고 있는 경우
        {
            // Default로 0번째 밴드를 Gray 모드로 그린다.
            XDMBand band = xrsFileInput.GetBandAt(0);

            // Gray Mode로 그리는 것을 설정
            newComp.Mode = eCompMode.Gray;

            // Composite의 0번에 Band 설정, Gray 모드에서는 0번 밴드만을 인식한다.
            newComp.SetBand(ref band, nBandIdx0);
            // 영상 Enhancement를 위해 Histogram의 범위 설정 (정규분포 95% 영역)
            newComp.SetCutType(eCompCutType.Ct95, 0);
            // 영상 Enhancement를 위해 Histogram 적용 시 전체 영역에 대한 Histogram(Band) 설정, Visible은 현재 영역
            newComp.SetStretchCoverage(eCompStretchCoverage.Band, 0);
            // 영상 Enhancement를 위해 Histogram의 Stretch형태 설정(Gaussian으로 설정)
            newComp.SetStretchType(eCompStretchType.Gaussian, 0);
        }
        else  // 3개 이상의 밴드를 가지고 있는 경우
        {
            XDMBand band1 = xrsFileInput.GetBandAt(nBandIdx0);
            XDMBand band2 = xrsFileInput.GetBandAt(nBandIdx1);
            XDMBand band3 = xrsFileInput.GetBandAt(nBandIdx2);
            // 파일 이름을 Composite이름으로 설정
            newComp.Name = xrsFileInput.FileName;

            newComp.Mode = eCompMode.RGB;  // RGB Mode로 그리는 것을 설정
            newComp.SetBand(ref band3, nBandIdx0);  // Composite의 0번에 Band설정, Blue Channel 설정
            newComp.SetBand(ref band2, nBandIdx1);  // Composite의 1번에 Band설정, Green Channel 설정
            newComp.SetBand(ref band1, nBandIdx2);  // Composite의 2번에 Band설정, Red Channel 설정

            for (int i = 0; i < 3; i++)
            {
                // 영상 Enhancement를 위해 Histogram의 범위 설정(정규분포 95% 영역)
                newComp.SetCutType(eCompCutType.Ct95, i);
                // 영상 Enhancement를 위해 Histogram 적용 시 전체 영역에 대한 
                // Histogram(Band) 설정, Visible은 현재 영역
                newComp.SetStretchCoverage(eCompStretchCoverage.Band, i);
                // 영상 Enhancement를 위해 Histogram의 Stretch형태 설정(Gaussian으로 설정)
                newComp.SetStretchType(eCompStretchType.Gaussian, i);
            }
        }
        // 생성된 Composite를 XDMCompManager 객체에 추가한다.
        return newComp;
    }
                                    
                            

4.5 [F5] 키를 눌러 프로그램을 실행하고 샘플영상을 선택하여 도시한다. [File]-[Open] 메뉴를 눌러 1.tif 파일을 연다. 다시 [File]-[Open] 메뉴를 눌러 2.tif 파일을 연다.

두 영상이 위치에 맞게 중첩된 결과를 확인할 수 있다.